/*
 * Copyright (C) 2008 Derek James and Philip Tucker
 * 
 * This file is part of ANJI (Another NEAT Java Implementation).
 * 
 * ANJI is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 * 
 * created by Philip Tucker on Oct 22, 2008
 */
package com.anji.moorph;

import java.util.Random;

import org.jgap.Allele;
import org.jgap.Chromosome;
import org.jgap.ChromosomeMaterial;
import org.jgap.Configuration;
import org.jgap.CrossoverReproductionOperator;

/**
 * @author Philip Tucker
 */
public class MoorphCrossoverReproductionOperator extends
    CrossoverReproductionOperator {

  /**
   * @param config
   * @param dominantChrom dominant parent
   * @param recessiveChrom recessive parent
   * @return ChromosomeMaterial offspring
   */
  protected ChromosomeMaterial reproduce(Configuration config,
      Chromosome dominantChrom, Chromosome recessiveChrom) {
    ChromosomeMaterial child = dominantChrom.cloneMaterial();
    child.setSecondaryParentId(recessiveChrom.getId());

    for (Allele allele : child.getAlleles()) {
      if (allele instanceof AppendageAllele) {
        Allele recessiveAllele = recessiveChrom.findMatchingGene(allele);
        if (recessiveAllele != null) {
          AppendageAllele appendageAllele = (AppendageAllele) allele;
          AppendageAllele recessiveAppendageAllele =
              (AppendageAllele) recessiveAllele;
          Random rand = config.getRandomGenerator();
          if (rand.nextBoolean()) {
            appendageAllele.setCount(recessiveAppendageAllele.getCount());
          }
          if (rand.nextBoolean()) {
            appendageAllele.setOrientation(recessiveAppendageAllele
                .getOrientation());
          }
          if (rand.nextBoolean()) {
            appendageAllele.setSize(recessiveAppendageAllele.getSize());
          }
        }
      }
    }

    return child;
  }

}
